package test.com.newproject.tool.helper;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Application;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.Formatter;

import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.ShellUtils;

import java.io.File;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * desc:
 * author：zjh
 * date:2017/12/19
 * time:15:31
 */
public enum UUIDHelper {
    INSTANCE;

    private Application app;
    private TelephonyManager tm;
    private String uuid;
    private String imei;
    private String ssn;
    private String androidID;
    private String ram;
    private String rom;
    private String mac;

    UUIDHelper() {

    }

    public void init(Application app) {
        this.app = app;
        this.tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
    }

    /**
     * 生成UUID
     * 如报错或取值为空
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.READ_PHONE_STATE"/>}</p>
     *
     * @return
     */
    public String createUUID(final Context context) {
        if (this.uuid != null) {
            return uuid;
        }

        UUID uuid = null;
        try {
            this.imei = getIMEI();
            this.ssn = tm.getSimSerialNumber();
            this.androidID = DeviceUtils.getAndroidID();
            this.ram = getRAM(context);
            this.rom = getROM(context);
            this.mac = DeviceUtils.getMacAddress();

            if (TextUtils.isEmpty(imei) || TextUtils.isEmpty(ssn) || TextUtils.isEmpty(androidID)) {
                showErrorDialog(context);
                return null;
            }

            uuid = new UUID(androidID.hashCode(), ((long) imei.hashCode() << 32) | ssn.hashCode());
        } catch (Exception e) {
            showErrorDialog(context);
            e.printStackTrace();
            return null;
        }

        if (uuid == null) {
            showErrorDialog(context);
            return null;
        }

        return this.uuid = uuid.toString();
    }

    public String getUUID() {
        return uuid;
    }

    public String getImei() {
        return imei;
    }

    public String getRam() {
        return ram;
    }

    public String getRom() {
        return rom;
    }

    public String getMac() {
        return mac;
    }

    public static void showErrorDialog(final Context context) {
        new AlertDialog.Builder(context)
                .setTitle("提示")
                .setMessage("无法获取您的手机信息，将会影响到您的额度评估。\r\n" +
                        "可能由以下原因引起：\r\n" +
                        "\r\n" +
                        "1.您未插入手机卡\r\n" +
                        "2.您未开启【读取手机信息】权限。\r\n" +
                        "\r\n" +
                        "您可插入手机卡或在系统设置中开启相关权限后重试。")
                .setPositiveButton("好的", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent intent = new Intent();
                        intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                        intent.setData(Uri.fromParts("package", context.getPackageName(), null));
                        context.startActivity(intent);
                        dialogInterface.dismiss();
                    }
                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                });
    }

    /**
     * 获取设备厂商
     * <p>如Xiaomi</p>
     *
     * @return 设备厂商
     */

    public String getManufacturer() {
        return Build.MANUFACTURER;
    }

    /**
     * 获取设备型号
     * <p>如MI2SC</p>
     *
     * @return 设备型号
     */
    public String getModel() {
        String model = Build.MODEL;
        if (model != null) {
            model = model.trim().replaceAll("\\s*", "");
        } else {
            model = "";
        }
        return model;
    }

    /**
     * 获取设备系统版本号
     *
     * @return 设备系统版本号
     */
    public int getSDKVersion() {
        return android.os.Build.VERSION.SDK_INT;
    }


    /**
     * 获取设备AndroidID
     *
     * @return AndroidID
     */
    @SuppressLint("HardwareIds")
    private String getAndroidID() {
        return Settings.Secure.getString(app.getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    /**
     * 获取IMEI码
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.READ_PHONE_STATE"/>}</p>
     *
     * @return IMEI码
     */
    @SuppressLint("HardwareIds")
    private String getIMEI() {
        return tm != null ? tm.getDeviceId() : null;
    }

    /**
     * 获取IMSI码
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.READ_PHONE_STATE"/>}</p>
     *
     * @return IMSI码
     */
    @SuppressLint({"HardwareIds"})
    private String getIMSI() {
        return tm != null ? tm.getSubscriberId() : null;
    }


    /**
     * 获取运存大小（相当于PC内存）
     *
     * @param context
     * @return
     */
    public static String getRAM(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(memoryInfo);

        String ram = Formatter.formatFileSize(context, memoryInfo.totalMem);

        try {
            if (ram.contains("GB")) {
                return ram.replaceAll("GB", "").trim();
            }

            if (ram.contains("G")) {
                return ram.replaceAll("G", "").trim();
            }
            return ram.trim();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取内部存储空间大小（相当于PC硬盘）
     *
     * @param context
     * @return
     */
    public static String getROM(Context context) {
        File file = Environment.getDataDirectory();
        StatFs statFs = new StatFs(file.getPath());
        long blockSize = statFs.getBlockSize();
        long totalBlocks = statFs.getBlockCount();
        long availableBlocks = statFs.getAvailableBlocks();

        String rom = Formatter.formatFileSize(context, blockSize * totalBlocks);

        try {
            if (rom.contains("GB")) {
                return rom.replaceAll("GB", "").trim();
            }

            if (rom.contains("G")) {
                return rom.replaceAll("G", "").trim();
            }
            return rom.trim();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取设备MAC地址
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
     *
     * @return MAC地址
     */
    public String getMacAddress() {
        String macAddress = getMacAddressByWifiInfo();
        if (!"02:00:00:00:00:00".equals(macAddress)) {
            return macAddress;
        }
        macAddress = getMacAddressByNetworkInterface();
        if (!"02:00:00:00:00:00".equals(macAddress)) {
            return macAddress;
        }
        macAddress = getMacAddressByFile();
        if (!"02:00:00:00:00:00".equals(macAddress)) {
            return macAddress;
        }
        return "please open wifi";
    }

    /**
     * 获取设备MAC地址
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
     *
     * @return MAC地址
     */
    @SuppressLint("HardwareIds")
    private String getMacAddressByWifiInfo() {
        try {
            @SuppressLint("WifiManagerLeak")
            WifiManager wifi = (WifiManager) app.getSystemService(Context.WIFI_SERVICE);
            if (wifi != null) {
                WifiInfo info = wifi.getConnectionInfo();
                if (info != null) return info.getMacAddress();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "02:00:00:00:00:00";
    }

    /**
     * 获取设备MAC地址
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
     *
     * @return MAC地址
     */
    private String getMacAddressByNetworkInterface() {
        try {
            List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface ni : nis) {
                if (!ni.getName().equalsIgnoreCase("wlan0")) continue;
                byte[] macBytes = ni.getHardwareAddress();
                if (macBytes != null && macBytes.length > 0) {
                    StringBuilder res1 = new StringBuilder();
                    for (byte b : macBytes) {
                        res1.append(String.format("%02x:", b));
                    }
                    return res1.deleteCharAt(res1.length() - 1).toString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "02:00:00:00:00:00";
    }

    /**
     * 获取设备MAC地址
     *
     * @return MAC地址
     */
    private static String getMacAddressByFile() {
        ShellUtils.CommandResult result = ShellUtils.execCmd("getprop wifi.interface", false);
        if (result.result == 0) {
            String name = result.successMsg;
            if (name != null) {
                result = ShellUtils.execCmd("cat /sys/class/net/" + name + "/address", false);
                if (result.result == 0) {
                    if (result.successMsg != null) {
                        return result.successMsg;
                    }
                }
            }
        }
        return "02:00:00:00:00:00";
    }
}
